package com.demo.sparseArray;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import java.io.*;

/**
 * 稀疏数组
 * 包括原始二维数组生成、二维数组转稀疏数组、稀疏数组转二维数组、稀疏数组转JSON字符串保存本地、从本地读取数据解析成二维数组
 */
public class SparseArray {

    public static void main(String[] args) throws IOException {
        SparseArray caseObj = new SparseArray();
        int[][] originalArray = caseObj.generatorArray();
        int[][] sparseArray = caseObj.toSparseArray(originalArray);
        // caseObj.toOriginalArray(sparseArray);
        String jsonString = JSON.toJSONString(sparseArray);
        //caseObj.stringToOriginArray(jsonString);
        String fileName = "F:\\download\\SparseArray.txt";
        caseObj.toFile(jsonString, fileName);
        String file = caseObj.readFile(fileName);
        caseObj.stringToOriginArray(file);
    }

    /**
     * 生成原始二维数组
     * @return
     */
    private int[][] generatorArray() {
        int[][] arr = new int[12][12];
        arr[2][4] = 1;
        arr[2][5] = 1;
        arr[3][4] = 1;
        arr[3][5] = 1;
        arr[3][6] = 2;
        arr[3][7] = 2;
        arr[4][5] = 2;
        arr[4][6] = 1;
        arr[5][5] = 1;
        arr[5][6] = 2;
        arr[5][7] = 2;
        System.out.println("原始二维数组为：");
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
        System.out.println();
        return arr;
    }

    /**
     * 原始数组转换成稀疏数组
     * @param originalArray
     * @return
     */
    private int[][] toSparseArray(int[][] originalArray) {
        // 获得原始数组行列、有效值初始化稀疏数组
        int sum = 0;
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                if (originalArray[i][j] != 0) {
                    sum += 1;
                }
            }
        }
        // 稀疏数组length为有效值个数+1
        int[][] sparseArray = new int[sum+1][3];
        // 行
        sparseArray[0][0] = originalArray.length;
        // 列
        sparseArray[0][1] = originalArray[0].length;
        // 有效数字
        sparseArray[0][2] = sum;
        int count = 0;
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                if (originalArray[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = originalArray[i][j];
                }
            }
        }
        // 输出稀疏数组
        System.out.println("转换后的稀疏数组为：");
        for (int i = 0; i < sparseArray.length; i++) {
            for (int j = 0; j < sparseArray[i].length; j++) {
                System.out.print(sparseArray[i][j] + "\t");
            }
            System.out.println();
        }
        System.out.println();
        return sparseArray;
    }

    /**
     * 稀疏数组转换为原始二维数组
     * @param sparseArray
     * @return
     */
    private int[][] toOriginalArray(int[][] sparseArray) {
        // 初始化原始数组
        int[][] originalArray = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 从第二个值开始，因为第一个值存的是原始数组的行列、有效值个数等信息
        for (int i = 1; i < sparseArray.length; i++) {
            // 由稀疏数组给原始数组赋值
            originalArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        System.out.println("转换后的二维数组为：");
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                System.out.print(originalArray[i][j] + "\t");
            }
            System.out.println();
        }
        return originalArray;
    }

    /**
     * 由JSON字符串转换成原始二维数组
     * @param jsonString
     * @return
     */
    private int[][] stringToOriginArray(String jsonString) {
        JSONArray objects = JSON.parseArray(jsonString);
        JSONArray s = (JSONArray) objects.get(0);
        // 初始化原始数组
        int[][] originalArray = new int[(int)s.get(0)][(int)s.get(1)];
        // 从第二个值开始，因为第一个值存的是原始数组的行列、有效值个数等信息
        for (int i = 1; i < objects.size(); i++) {
            JSONArray se = (JSONArray) objects.get(i);
            originalArray[(int)se.get(0)][(int)se.get(1)] = (int)se.get(2);
        }
        System.out.println("JSON字符串转换为二维数组：");
        for (int i = 0; i < originalArray.length; i++) {
            for (int j = 0; j < originalArray[i].length; j++) {
                System.out.print(originalArray[i][j] + "\t");
            }
            System.out.println();
        }
        return originalArray;
    }

    /**
     * 将JSON字符串保存为文件
     * @param jsonString
     * @param fileName 电脑本地文件
     */
    private void toFile(String jsonString, String fileName) {
        File file = new File(fileName);
        FileWriter fileWriter = null;
        if (!file.exists()) {
            try {
                file.createNewFile();
                fileWriter = new FileWriter(file);
                char[] chars = jsonString.toCharArray();
                fileWriter.write(chars);
                fileWriter.flush();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            } finally {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 从文件读取内容
     * @param fileName
     * @return
     * @throws IOException
     */
    private String readFile(String fileName) throws IOException {
        File file = new File(fileName);
        FileReader reader = new FileReader(file);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String line = null;
        System.out.println("文件读取内容为：");
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
            System.out.println();
            return line;
        }
        reader.close();
        bufferedReader.close();
        return line;
    }
}
